package com.pet.platform.service.impl;

import com.pet.platform.exception.BusinessException;
import com.pet.platform.common.Constants;
import com.pet.platform.common.PageResult;
import com.pet.platform.dto.PetDTO;
import com.pet.platform.dto.PetQueryDTO;
import com.pet.platform.entity.Pet;
import com.pet.platform.entity.User;
import com.pet.platform.mapper.PetMapper;
import com.pet.platform.service.PetService;
import com.pet.platform.service.UserService;
import com.pet.platform.util.FileUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PetServiceImpl implements PetService {

    @Resource
    private PetMapper petMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private FileUtil fileUtil;

    @Override
    public Pet findById(Long id) {
        return petMapper.findById(id);
    }

    @Override
    public PageResult<PetDTO> findPage(PetQueryDTO queryDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("name", queryDTO.getName());
        params.put("category", queryDTO.getCategory());
        params.put("breed", queryDTO.getBreed());
        params.put("gender", queryDTO.getGender());
        params.put("adoptionStatus", queryDTO.getAdoptionStatus());
        params.put("ownerId", queryDTO.getOwnerId());
        params.put("offset", (queryDTO.getPageNum() - 1) * queryDTO.getPageSize());
        params.put("pageSize", queryDTO.getPageSize());
        params.put("orderBy", queryDTO.getOrderBy());
        params.put("isAsc", queryDTO.getIsAsc());

        List<Pet> pets = petMapper.findList(params);
        Long total = petMapper.count(params);

        List<PetDTO> petDTOs = pets.stream().map(pet -> {
            PetDTO dto = new PetDTO();
            BeanUtils.copyProperties(pet, dto);
            if (pet.getOwner() != null) {
                dto.setOwnerName(pet.getOwner().getUsername());
            }
            return dto;
        }).collect(Collectors.toList());

        return new PageResult<>(petDTOs, total, queryDTO.getPageNum(), queryDTO.getPageSize());
    }

    @Override
    @PreAuthorize("hasRole('ADMIN')")
    @Transactional(rollbackFor = Exception.class)
    public void create(PetDTO petDTO) {
        Pet pet = new Pet();
        BeanUtils.copyProperties(petDTO, pet);
        pet.setAdoptionStatus("AVAILABLE");
        petMapper.insert(pet);
    }

    @Override
    @PreAuthorize("hasRole('ADMIN')")
    @Transactional(rollbackFor = Exception.class)
    public void update(Long id, PetDTO petDTO) {
        Pet pet = findById(id);
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        BeanUtils.copyProperties(petDTO, pet);
        pet.setId(id);
        petMapper.update(pet);
    }

    @Override
    @PreAuthorize("hasRole('ADMIN')")
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        Pet pet = findById(id);
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        if (!"AVAILABLE".equals(pet.getAdoptionStatus())) {
            throw new BusinessException("已被领养的宠物不能删除");
        }

        // 删除宠物图片
        if (pet.getImageUrl() != null && !pet.getImageUrl().isEmpty()) {
            fileUtil.deleteFile(pet.getImageUrl());
        }

        petMapper.delete(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void adopt(Long id) {
        Pet pet = findById(id);
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        if (!"AVAILABLE".equals(pet.getAdoptionStatus())) {
            throw new BusinessException("该宠物已被领养");
        }

        Long currentUserId = userService.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }

        pet.setAdoptionStatus("ADOPTED");
        pet.setOwnerId(currentUserId);
        petMapper.update(pet);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelAdoption(Long id) {
        Pet pet = findById(id);
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        if (!"ADOPTED".equals(pet.getAdoptionStatus())) {
            throw new BusinessException("该宠物未被领养");
        }

        Long currentUserId = userService.getCurrentUserId();
        User currentUser = userService.findById(currentUserId);
        
        // 检查是否为管理员或宠物主人
        if (!currentUser.getRole().equals("ADMIN") && !pet.getOwnerId().equals(currentUserId)) {
            throw new BusinessException("无权取消他人的领养");
        }

        pet.setAdoptionStatus("AVAILABLE");
        pet.setOwnerId(null);
        petMapper.update(pet);
    }

    @Override
    @PreAuthorize("hasRole('ADMIN')")
    @Transactional(rollbackFor = Exception.class)
    public String updateImage(Long id, MultipartFile file) {
        Pet pet = findById(id);
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        // 删除旧图片
        if (pet.getImageUrl() != null && !pet.getImageUrl().isEmpty()) {
            fileUtil.deleteFile(pet.getImageUrl());
        }

        // 上传新图片
        String imageUrl = fileUtil.uploadFile(file, "pets");

        // 更新宠物图片
        Pet updatePet = new Pet();
        updatePet.setId(id);
        updatePet.setImageUrl(imageUrl);
        petMapper.update(updatePet);

        return imageUrl;
    }

    @Override
    public List<PetDTO> findByOwnerId(Long ownerId) {
        List<Pet> pets = petMapper.findByOwnerId(ownerId);
        return pets.stream().map(pet -> {
            PetDTO dto = new PetDTO();
            BeanUtils.copyProperties(pet, dto);
            if (pet.getOwner() != null) {
                dto.setOwnerName(pet.getOwner().getUsername());
            }
            return dto;
        }).collect(Collectors.toList());
    }
} 